package com.oig.sys.auth.controller;


import cn.hutool.core.util.StrUtil;
import com.oig.common.exception.BadRequestException;
import com.oig.common.module.SysPageInfo;
import com.oig.common.module.SysRequest;
import com.oig.common.module.SysResponse;
import com.oig.common.validator.GroupAdd;
import com.oig.common.validator.GroupChange;
import com.oig.common.validator.GroupEdit;
import com.oig.sys.auth.dto.UserDto;
import com.oig.sys.auth.service.ITbUserService;
import com.oig.sys.auth.vo.UserVo;
import com.oig.sys.log.annotation.SysLog;
import com.oig.sys.security.util.SecurityUtil;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Tag(name = "8-用户管理")
@RestController
@RequestMapping(value = "/user")
@Slf4j
public class TbUserController {

    private final ITbUserService userService;

    @Autowired
    public TbUserController(ITbUserService userService){
        this.userService = userService;
    }

    @PreAuthorize("@pms.hasPermission('/user/addUser')")
    @SysLog(value="添加系统用户",apiUrl="/user/addUser")
    @Operation(summary = "添加系统用户,可以批量增加用户所属部门、岗位、角色等")
    @PostMapping("/addUser")
    public UserVo addUser(@RequestBody @Validated(GroupAdd.class) UserDto userDto){
        log.info("add user :{}",userDto);
        if (SecurityUtil.getDefineUserMain().getTenantId()>0 && !SecurityUtil.getDefineUserMain().getTenantId().equals(userDto.getTenantId())){
            throw new BadRequestException("请选择所属公司");
        }
        return this.userService.addUser(userDto);
    }

    @PreAuthorize("@pms.hasPermission('/user/updateUser')")
    @SysLog(value="修改系统用户",apiUrl="/user/updateUser")
    @Operation(summary = "修改系统用户")
    @PostMapping("/updateUser")
    public UserVo updateUser(@RequestBody @Validated(GroupEdit.class) UserDto userDto){
        log.info("update user :{}",userDto);
        SecurityUtil.getDefineUserMain().checkTenantPermission(userDto.getTenantId());
        return this.userService.updateUser(userDto);
    }

    @PreAuthorize("@pms.hasPermission('/user/resetPwd')")
    @SysLog(value="重置用户密码",apiUrl="/user/resetPwd")
    @Operation(summary = "重置用户密码")
    @PostMapping(value = "/resetPwd/{userId}")
    public SysResponse<Integer> resetPwd(@PathVariable("userId") Integer userId){
        log.info("revert User userId:{}",userId);
        this.userService.resetPwd(userId);
        return SysResponse.ok(userId,"重置用户成功");
    }

    @PreAuthorize("@pms.hasPermission('/user/cancelUser')")
    @SysLog(value="逻辑删除用户",apiUrl="/user/cancelUser")
    @Operation(summary = "逻辑删除用户")
    @PostMapping("/cancelUser/{userId}")
    public SysResponse<Integer> cancelUser(@PathVariable("userId") Integer userId){
        log.info("cancel delUser:{}", userId);
        this.userService.cancelUser(userId);
        return SysResponse.ok(userId,"删除成功") ;
    }


    @PreAuthorize("@pms.hasPermission('/user/revertUser')")
    @SysLog(value="恢复用户",apiUrl="/user/revertUser")
    @Operation(summary = "恢复用户")
    @PostMapping(value = "/revertUser/{userId}")
    public SysResponse<Integer> revertUser(@PathVariable("userId") Integer userId){
        log.info("revert User userId:{}",userId);
        this.userService.revertUser(userId);
        return SysResponse.ok(userId,"恢复成功");
    }


    @PreAuthorize("@pms.hasPermission('/user/delUser')")
    @SysLog(value="物理删除用户",apiUrl="/user/delUser")
    @Operation(summary = "物理删除用户,物理删除用户及关系数据,先提供，但产生业务数据后不能操作")
    @PostMapping(value = "/delUser/{userId}")
    public SysResponse<Integer> delUser(@PathVariable("userId") Integer userId){
        log.warn("del User id={}", userId) ;
        this.userService.delUser(userId);
        return SysResponse.ok(userId,"物理删除成功");
    }


    @Operation(summary = "查看,查看详情，如果有子表则包含子表信息")
    @PostMapping(value = "/info/{userId}")
    public UserVo info(@PathVariable("userId") Integer userId){
        log.info("info UserVo id={}", userId) ;
        return this.userService.getUserInfo(userId);
    }

    @Operation(summary = "查询用户,用于部门选择人员，根据租户查询，租户id必传，分页")
    @PostMapping(value = "/queryUserAsPage")
    public SysPageInfo<UserVo> queryUserAsPage(@RequestBody SysRequest<UserDto> userRequest){
        log.info("query all user, {}", userRequest);
        if (userRequest.getParamDto()==null){
            UserDto userDto = new UserDto();
            userDto.setTenantId(SecurityUtil.getDefineUserMain().getTenantId());
            userRequest.setParamDto(userDto);
        } else if (userRequest.getParamDto().getTenantId()==null){
            userRequest.getParamDto().setTenantId(SecurityUtil.getDefineUserMain().getTenantId());
        }
        SecurityUtil.getDefineUserMain().checkTenantPermission(userRequest.getParamDto().getTenantId());
        return this.userService.listAllUser(userRequest);
    }


    @Operation(summary = "查询用户,用于部门选择人员，根据租户查询，租户id必传，不分页")
    @PostMapping(value = "/listAllUser")
    public List<UserVo> listAllUser(@RequestBody SysRequest<UserDto> userRequest){
        log.info("list all user, {}", userRequest);
        return this.queryUserAsPage(userRequest).getList();
    }


    @Operation(summary = "查询租户用户 租户id必传，不分页")
    @PostMapping(value = "/listAllTenUser/{tenantId}")
    public List<UserVo> listAllTenantUser(@PathVariable("tenantId") Integer tenantId){
        log.info("list all tenant user, {}", tenantId);
        if (tenantId==0 && SecurityUtil.getUserForIfNullBuild().getTenantId()!=0){
            tenantId = SecurityUtil.getUserForIfNullBuild().getTenantId();
        } else {
            SecurityUtil.getDefineUserMain().checkTenantPermission(tenantId);
        }
        return this.userService.listAllTenantUser(tenantId);
    }



    @Operation(summary = "查询部门用户,根据部门查询，部门id必传，不分页")
    @PostMapping(value = "/listAllDeptUser/{deptId}")
    public List<UserVo> listAllDeptUser(@PathVariable("deptId") Integer deptId){
        log.info("list all dept user, {}", deptId);
        return this.userService.listAllDeptUser(deptId);
    }


    @Operation(summary = "根据用户Id查询用户,仅仅返回用户基本资料")
    @PostMapping(value = "/getUserById/{userId}")
    public UserVo getUserById(@PathVariable("userId") Integer userId){
        log.info("getUserById userId:{}", userId);
        return this.userService.getUserById(userId);
    }

    @Operation(summary = "根据用户Id查询用户,仅仅返回用户基本资料")
    @PostMapping(value = "/loadUsersByUserIds")
    public List<UserVo> loadUsersByUserIds(@RequestBody List<Integer> userIdList){
        log.info("getUserById userIdList:{}", userIdList);
        return this.userService.listUserByUserIdList(userIdList);
    }

    @Operation(summary = "根据工号查询用户,仅仅返回用户基本资料")
    @PostMapping(value = "/getUserByCode/{code}")
    public UserVo getUserByCode(@PathVariable("code") String code){
        log.info("getUserByCode code:{}", code);
        return this.userService.getUserByCode(code);
    }

    @Operation(summary = "根据工号查询用户,仅仅返回用户基本资料")
    @PostMapping(value = "/loadUsersByUserCodes")
    public List<UserVo> loadUsersByUserCodes(@RequestBody List<String> userCodeList){
        log.info("getUserByCode userCodeList:{}", userCodeList);
        return this.userService.listUserByUserCodeList(userCodeList);
    }


    /** ---------用户自身操作- start-----*/
    @SysLog(value="当前登录用户修改密码",apiUrl="/user/updatePwd")
    @Operation(summary = "当前登录用户修改密码")
    @PostMapping("/updatePwd")
    public SysResponse<Integer> updatePwd(@RequestBody @Validated(GroupChange.class) UserDto userDto){
        log.info(" user update password:{}",userDto);
        this.userService.updatePwd(userDto);
        return SysResponse.ok(null,"密码修改成功") ;
    }


    @SysLog(value="当前登录用户设置默认应用",apiUrl="/user/setDefaultSys")
    @Operation(summary = "当前登录用户设置默认应用")
    @PostMapping("/setDefaultSys")
    public SysResponse<Integer> setDefaultSys(@RequestParam("systemId") Integer systemId, @RequestParam("systemName") String systemName){
        log.info(" user setDefaultSys:{}-{}",systemId, systemName);
        if (systemId==null|| StrUtil.isBlank(systemName)){
            throw new BadRequestException("请选择一个应用") ;
        }
        this.userService.setDefaultSystem(systemId, systemName);
        return SysResponse.ok(systemId,"设置成功") ;
    }




    /**
     * 提供SDK 给认证授权中心查询
     * @param username 用户名
     * @return 用户信息
     */
    @Operation(summary = "根据用户名或工号查询用户")
    @PostMapping(value = "/loadUser/{username}")
    public UserVo loadUserByUsername(@PathVariable("username") String username){
        log.info("loadUserByUsername username:{}", username);
        return this.userService.loadUserByCodeOrUsername(username);
    }


    /**------auth-server和oauth-security 合并成一个服务比较好---------*/
    @Hidden
    @PostMapping(value = "/updateLoginSuccess")
    public void updateLoginSuccess(@RequestBody UserDto userDto){
        log.info("updateLoginSuccess:{}", userDto);
        if (userDto.getId()!=null){
            this.userService.updateLoginSucess(userDto);
        }
    }

    @Hidden
    @PostMapping(value = "/updateLoginFail")
    public void updateLoginFail(@RequestBody UserDto userDto){
        log.info("updateLoginFail:{}", userDto);
        if (StringUtils.isNotBlank(userDto.getUsername())){
            this.userService.updateLoginFail(userDto);
        }
    }


}
